package ua.yandex.shad.tempseries;

public class TemperatureSeriesAnalysis {

    private final double[] temperatureSeries;
    private static final int maxTemperature = -273;

    public TemperatureSeriesAnalysis(double[] temperatureSeries) {
        if (temperatureSeries == null) {
            throw new NullPointerException();
        }
        for (double d : temperatureSeries) {
            if (d < maxTemperature) {
                throw new IllegalTemperatureValueException();
            }
        }
        this.temperatureSeries = temperatureSeries;
    }

    private boolean checkLength() {
        boolean result = false;
        if (temperatureSeries.length == 0) {
            result = true;
        }
        return result;
    }

    public double calcAverageTemp() {
        double sum = 0;
        if (checkLength()) {
            return 0;
        } else {
            for (double d : temperatureSeries) {
                sum += d;
            }
            return sum / temperatureSeries.length;
        }
    }

    public double calcTempDeviation() {
        if (checkLength()) {
            return 0;
        } else {
            double sum = 0;
            double average = calcAverageTemp();
            for (double d : temperatureSeries) {
                sum += (average - d) * (average - d);
            }
            return sum / temperatureSeries.length;
        }
    }

    public double findTempClosestToZero() {
        return findTempClosestToValue(0);
    }

    public double findTempClosestToValue(double tempValue) {
        if (checkLength()) {
            return 0;
        } else {
            double tempClosestToValue = temperatureSeries[0];

            for (int i = 1; i < temperatureSeries.length; i++) {
                if (Math.abs(tempValue - temperatureSeries[i]) < Math.abs(tempValue - tempClosestToValue)) {
                    tempClosestToValue = temperatureSeries[i];
                } else if (Math.abs(tempValue - temperatureSeries[i]) == Math.abs(tempValue - tempClosestToValue)) {
                    tempClosestToValue = Math.max(temperatureSeries[i], tempClosestToValue);
                }
            }
            return tempClosestToValue;
        }

    }

    public double[] findTempsLessThen(double tempValue) {
        double tempMas[] = new double[temperatureSeries.length];
        int index = 0;

        if (checkLength()) {
            return new double[]{};
        } else {
            for (double d : temperatureSeries) {
                if (d < tempValue) {
                    tempMas[index] = d;
                    index++;
                }

            }
            double resMas[] = new double[index];
            for (int i = 0; i < index; i++) {
                resMas[i] = tempMas[i];
            }
            return resMas;
        }
    }

    public double[] findTempsGreaterThen(double tempValue) {
        double tempMas[] = new double[temperatureSeries.length];
        int index = 0;

        if (checkLength()) {
            return tempMas;
        } else {
            for (double d : temperatureSeries) {
                if (d > tempValue) {
                    tempMas[index] = d;
                    index++;
                }
            }
            double resMas[] = new double[index];
            for (int i = 0; i < index; i++) {
                resMas[i] = tempMas[i];
            }
            return resMas;
        }
    }

    public double[] forecatsTemp() throws NotEnoughValuesToForecastException, IllegalTemperatureValueException {
        if (temperatureSeries.length < 10) {
            throw new NotEnoughValuesToForecastException();
        }
        double ResMas[] = new double[3];
        return ResMas;
    }
}
